#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/signal.h>
#include <string.h>
#include <sys/stat.h>
#include <syslog.h>
#include "./dbHandler/dbHandler.h"
#include "../sockcomADT/sockcomADT.h"
#include "../clsv/clsv.h"
#include "../clsv/aux.h"
#include "../error/error.h"
#include "../tickets/tickets.h"
#include "server.h"
#include "svstub.h"

#define MAX_FILES    32

extern Comm comm;
extern serverInfoT serverInfo;

int
passwd(char * oldpass, char * newpass, int login)
{
	STAT status;
	/* check if oldpassword is correct*/
	if ((status = checkPass(serverInfo.db, login, oldpass)) < 0)
		return status;
	else
		return changePass(serverInfo.db, login, newpass);
}

int
list_categories(char ** resp)
{
	int bytes;
	
	bytes = requestCatList(serverInfo.db, resp);	
	return bytes;
}

int
list_users(char ** resp)
{
	int bytes;
	
	requestUsrList(serverInfo.db, resp);
	bytes = strlen(*resp)+1;
	
	return bytes;
}

int
list_files(char ** resp, char * category)
{
	int bytes;
	
	bytes = requestFList(serverInfo.db, category, resp);
	
	return bytes;
}

int
get_ticket(char * filename, ticketP * tickp, int login)
{
	int pid;
	char * ip;
	
	/*check if file exists in database and in the server's folder*/
	if (!checkFile(serverInfo.db, filename) || !fileExists(filename))
		return -ERROR_FILE_NOT_EXISTS;
	/*check if user is currently downloading a file */
	if (downloading(serverInfo.db, login))
		return -ERROR_ALLRDY_DOWNLADING;
	
	/* if ther user has tickets left for the day create the new ticket and 
	 * increase the tickets requested for the day */
	if (TicketsLeft(serverInfo.db, login))
	{
		pid = getpid();
		ip = printIP(comm);
		if (CreateTicket(serverInfo.db, filename, pid, tickp, ip) < 0)
			return -ERROR_SERVER_CRITIC;
		if (IncTickets(serverInfo.db, login) < 0)
			return -ERROR_SERVER_CRITIC;
		
		return OK;
	}
	else
		return -ERROR_NO_TICKETS_LEFT;
}

int
use_ticket(ticketT md5, ticketP * tickp, int login)
{	
	int status;
	int ctime;
	char * ip;
	
	ip = printIP(comm);
	/*check if ticket exists for the user's ip that requested it */
	if (!TicketExists(serverInfo.db, md5, ip))
	{
		strcpy(tickp->id, md5);
		return -ERROR_TICKET_NOT_EXISTS;
	}
	/* check if the download connections have reached the maximum*/
	if (countConn(serverInfo.db) >= serverInfo.connections)
		return -ERROR_MAX_CONN_REACHED;
	
	/* get parameters from the ticket that ir being exchanged */
	if ((status = GetTicketParameters(serverInfo.db, md5, tickp)) < 0)
		return status;
	
	ctime = time(NULL);
	
	/* check if the current time is between enabled and expired */ 
	if (tickp->etime > ctime && tickp->dtime <= ctime)
	{
		if (tickp->retries == 2)
		{
			if (RemoveTicket(serverInfo.db, md5) < 0)
				return -ERROR_SERVER_CRITIC;
			return -ERROR_TICKET_LOST;
		}
		else
		{
			if (IncreaseRetries(serverInfo.db, md5, tickp) < 0)
				return -ERROR_SERVER_CRITIC;
			return -ERROR_TICKET_NA;
		}
	}
	else
	{
		if (tickp->etime <= ctime && tickp->ftime >= ctime)
		{
			if (RemoveTicket(serverInfo.db, md5) < 0)
				return -ERROR_SERVER_CRITIC;
			return OK;
		}
		else
		{
			if (RemoveTicket(serverInfo.db, md5) < 0)
				return -ERROR_SERVER_CRITIC;
			return -ERROR_TICKET_EXPIRED;
		}
	}
}

int
upload(char * filename, int size)
{
	int ret;
	/* check if the server has enough space available */
	if (serverInfo.load + size > serverInfo.capacity)
		return -ERROR_UPLOAD_NO_SPACE;
	
	/* checks if filename already exists in the datase */
	if ((ret = checkFile(serverInfo.db, filename)) > 0)
		return -ERROR_UPLOAD_FILE_EXISTS;
	
	/*checks if filename already exists in file directory (for inconsistencies)*/
	if ((ret = checkFilename(filename)) < 0)
		return -ERROR_UPLOAD_INVALID_FILENAME;
	
	return OK;
}
